<!DOCTYPE html>
<html>

<head>
  <title>Quarkus - Class Loading Reference</title>
  <script id="adobe_dtm" src="https://www.redhat.com/dtm.js" type="text/javascript"></script>
  <script src="/assets/javascript/highlight.pack.js" type="text/javascript"></script>
  <META HTTP-EQUIV='Content-Security-Policy' CONTENT="default-src 'none'; script-src 'self' 'unsafe-eval' 'sha256-ANpuoVzuSex6VhqpYgsG25OHWVA1I+F6aGU04LoI+5s=' 'sha256-ipy9P/3rZZW06mTLAR0EnXvxSNcnfSDPLDuh3kzbB1w=' js.bizographics.com https://www.redhat.com assets.adobedtm.com jsonip.com https://ajax.googleapis.com https://www.googletagmanager.com https://www.google-analytics.com https://use.fontawesome.com; style-src 'self' https://fonts.googleapis.com https://use.fontawesome.com; img-src 'self' *; media-src 'self' ; frame-src https://www.googletagmanager.com https://www.youtube.com; frame-ancestors 'none'; base-uri 'none'; object-src 'none'; form-action 'none'; font-src 'self' https://use.fontawesome.com https://fonts.gstatic.com;">
  <META HTTP-EQUIV='X-Frame-Options' CONTENT="DENY">
  <META HTTP-EQUIV='X-XSS-Protection' CONTENT="1; mode=block">
  <META HTTP-EQUIV='X-Content-Type-Options' CONTENT="nosniff">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="Quarkus: Supersonic Subatomic Java">
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:site" content="@QuarkusIO"> 
  <meta name="twitter:creator" content="@QuarkusIO">
  <meta property="og:url" content="https://quarkus.io/guides/class-loading-reference" />
  <meta property="og:title" content="Quarkus - Class Loading Reference" />
  <meta property="og:description" content="Quarkus: Supersonic Subatomic Java" />
  <meta property="og:image" content="/assets/images/quarkus_card.png" />
  <link rel="canonical" href="https://quarkus.io/guides/class-loading-reference">
  <link rel="shortcut icon" type="image/png" href="/favicon.ico" >
  <link rel="stylesheet" href="https://quarkus.io/guides/stylesheet/config.css" />
  <link rel="stylesheet" href="/assets/css/main.css" />
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
  <link rel="alternate" type="application/rss+xml"  href="https://quarkus.io/feed.xml" title="Quarkus">
  <script src="https://quarkus.io/assets/javascript/goan.js" type="text/javascript"></script>
  <script src="https://quarkus.io/assets/javascript/hl.js" type="text/javascript"></script>
</head>

<body class="guides">
  <!-- Google Tag Manager (noscript) -->
  <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NJWS5L"
  height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->

  <div class="nav-wrapper">
  <div class="grid-wrapper">
    <div class="width-12-12">
      <input type="checkbox" id="checkbox" />
      <nav id="main-nav" class="main-nav">
  <div class="container">
    <div class="logo-wrapper">
      
        <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_600px_reverse.png" class="project-logo" title="Quarkus"></a>
      
    </div>
    <label class="nav-toggle" for="checkbox">
      <i class="fa fa-bars"></i>
    </label>
    <div id="menu" class="menu">
      <span>
        <a href="/get-started/" class="">Get Started</a>
      </span>
      <span>
        <a href="/guides/" class="active">Guides</a>
      </span>
      <span>
        <a href="/community/" class="">Community</a>
      </span>
      <span>
        <a href="/support/" class="">Support</a>
      </span>
      <span>
        <a href="/blog/" class="">Blog</a>
      </span>
      <span>
        <a href="https://code.quarkus.io" class="button-cta secondary white">Start Coding</a>
      </span>
    </div>
  </div>
      </nav>
    </div>
  </div>
</div>

  <div class="content">
    <div class="guide">
  <div class="width-12-12">
    <h1 class="text-caps">Quarkus - Class Loading Reference</h1>
    <div class="hide-mobile toc"><ul class="sectlevel1">
<li><a href="#reading-class-bytecode">Reading Class Bytecode</a></li>
<li><a href="#bootstrapping-quarkus">Bootstrapping Quarkus</a>
<ul class="sectlevel2">
<li><a href="#current-run-modes">Current Run Modes</a></li>
<li><a href="#notes-on-transformer-safety">Notes on Transformer Safety</a></li>
</ul>
</li>
<li><a href="#classloader-implementations">ClassLoader Implementations</a></li>
<li><a href="#isolated-classloaders">Isolated ClassLoaders</a>
<ul class="sectlevel2">
<li><a href="#parent-first-dependencies">Parent First Dependencies</a></li>
<li><a href="#banned-dependencies">Banned Dependencies</a></li>
</ul>
</li>
</ul></div>
    <div>
      <div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>This document explains the Quarkus class loading architecture. It is intended for extension
authors and advanced users who want to understand exactly how Quarkus works.</p>
</div>
<div class="paragraph">
<p>The Quarkus class loading architecture is slightly different depending on the mode that
the application is run in. When running a production application everything is loaded
in the system ClassLoader, so it is a completely flat class path. This also applies to
native image mode which does not really support multiple ClassLoaders, and is based on
a normal production Quarkus application.</p>
</div>
<div class="paragraph">
<p>For all other use cases (e.g. tests, dev mode, and building the application) Quarkus
uses the class loading architecture outlined here.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="reading-class-bytecode"><a class="anchor" href="#reading-class-bytecode"></a>Reading Class Bytecode</h2>
<div class="sectionbody">
<div class="paragraph">
<p>It is important to use the correct <code>ClassLoader</code>. The recommended approach is to get it by calling the
<code>Thread.currentThread().getContextClassLoader()</code> method.</p>
</div>
<div class="paragraph">
<p>Example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@BuildStep
GeneratedClassBuildItem instrument(final CombinedIndexBuildItem index) {
    final String classname = "com.example.SomeClass";
    final ClassLoader cl = Thread.currentThread().getContextClassLoader();
    final byte[] originalBytecode = IoUtil.readClassAsBytes(cl, classname);
    final byte[] enhancedBytecode = ... // class instrumentation from originalBytecode
    return new GeneratedClassBuildItem(true, classname, enhancedBytecode));
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="bootstrapping-quarkus"><a class="anchor" href="#bootstrapping-quarkus"></a>Bootstrapping Quarkus</h2>
<div class="sectionbody">
<div class="paragraph">
<p>All Quarkus applications are created by the QuarkusBootstrap class in the <code>independent-projects/bootstrap</code> module. This
class is used to resolve all the relevant dependencies (both deployment and runtime) that are needed for the Quarkus
application. The end result of this process is a <code>CuratedApplication</code>, which contains all the class loading information
for the application.</p>
</div>
<div class="paragraph">
<p>The <code>CuratedApplication</code> can then be used to create an <code>AugmentAction</code> instance, which can create production application
and start/restart runtime ones. This application instance exists within an isolated ClassLoader, it is not necessary
to have any of the Quarkus deployment classes on the class path as the curate process will resolve them for you.</p>
</div>
<div class="paragraph">
<p>This bootstrap process should be the same no matter how Quarkus is launched, just with different parameters passed in.</p>
</div>
<div class="sect2">
<h3 id="current-run-modes"><a class="anchor" href="#current-run-modes"></a>Current Run Modes</h3>
<div class="paragraph">
<p>At the moment we have the following use cases for bootstrapping Quarkus:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Maven creating production application</p>
</li>
<li>
<p>Maven dev mode</p>
</li>
<li>
<p>Gradle creating a production application</p>
</li>
<li>
<p>Gradle dev mode</p>
</li>
<li>
<p>QuarkusTest (Maven, Gradle and IDE)</p>
</li>
<li>
<p>QuarkusUnitTest (Maven, Gradle and IDE)</p>
</li>
<li>
<p>QuarkusDevModeTest (Maven, Gradle and IDE)</p>
</li>
<li>
<p>Arquillian Adaptor</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>One of the goals of this refactor is to have all these different run modes boot Quarkus in fundamentally the same way.</p>
</div>
</div>
<div class="sect2">
<h3 id="notes-on-transformer-safety"><a class="anchor" href="#notes-on-transformer-safety"></a>Notes on Transformer Safety</h3>
<div class="paragraph">
<p>A ClassLoader is said to be 'transformer safe' if it is safe to load classes in the class loader before the transformers
are ready. Once a class has been loaded it cannot be changed, so if a class is loaded before the transformers have been
prepared this will prevent the transformation from working. Loading classes in a transformer safe ClassLoader will not
prevent the transformation, as the loaded class is not used at runtime.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="classloader-implementations"><a class="anchor" href="#classloader-implementations"></a>ClassLoader Implementations</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Quarkus has the following ClassLoaders:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Base ClassLoader</dt>
<dd>
<p>This is usually the normal JVM System ClassLoader. In some environments such as Maven it may be different. This ClassLoader
is used to load the bootstrap classes, and other ClassLoader instances will delegate the loading of JDK classes to it.</p>
</dd>
<dt class="hdlist1">Augment ClassLoader</dt>
<dd>
<p>This loads all the <code>-deployment</code> artifacts and their dependencies, as well as other user dependencies. It does not load the
application root or any hot deployed code. This ClassLoader is persistent, even if the application restarts it will remain
(which is why it cannot load application classes that may be hot deployed). Its parent is the base ClassLoader, and it is
transformer safe.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>At present this can be configured to delegate to the Base ClassLoader, however the plan is for this option to go away and
always have this as an isolated ClassLoader. Making this an isolated ClassLoader is complicated as it means that all
the builder classes are isolated, which means that use cases that want to customise the build chains are slightly more complex.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Deployment ClassLoader</dt>
<dd>
<p>This can load all application classes, its parent is the Augment ClassLoader so it can also load all deployment classes.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>This ClassLoader is non-persistent, it will be re-created when the application is started, and is isolated. This ClassLoader
is the context ClassLoader that is used when running the build steps. It is also transformer safe.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Base Runtime ClassLoader</dt>
<dd>
<p>This loads all the runtime extension dependencies, as well as other user dependencies (note that this may include duplicate
copies of classes also loaded by the Augment ClassLoader). It does not load the application root or any hot deployed
code. This ClassLoader is persistent, even if the application restarts it will remain (which is why it cannot load
application classes that may be hot deployed). Its parent is the base ClassLoader.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>This loads code that is not hot-reloadable, but it does support transformation (although once the class is loaded this
transformation is no longer possible). This means that only transformers registered in the first application start
will take effect, however as these transformers are expected to be idempotent this should not cause problems. An example
of the sort of transformation that might be required here is a Panache entity packaged in an external jar. This class
needs to be transformed to have its static methods implemented, however this transformation only happens once, so
restarts use the copy of the class that was created on the first start.</p>
</div>
<div class="paragraph">
<p>This ClassLoader is isolated from the Augment and Deployment ClassLoaders. This means that it is not possible to set
values in a static field in the deployment side, and expect to read it at runtime. This allows dev and test applications
to behave more like a production application (production applications are isolated in that they run in a whole new JVM).</p>
</div>
<div class="paragraph">
<p>This also means that the runtime version can be linked against a different set of dependencies, e.g. the hibernate
version used at deployment time might want to include ByteBuddy, while the version used at runtime does not.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Runtime Class Loader</dt>
<dd>
<p>This ClassLoader is used to load the application classes and other hot deployable resources. Its parent is the base runtime
ClassLoader, and it is recreated when the application is restarted.</p>
</dd>
</dl>
</div>
</div>
</div>
<div class="sect1">
<h2 id="isolated-classloaders"><a class="anchor" href="#isolated-classloaders"></a>Isolated ClassLoaders</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The runtime ClassLoader is always isolated. This means that it will have its own copies of almost every class from the
resolved dependency list. The exception to this are:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>JDK classes</p>
</li>
<li>
<p>Classes from artifacts that extensions have marked as parent first (more on this later).</p>
</li>
</ul>
</div>
<div class="sect2">
<h3 id="parent-first-dependencies"><a class="anchor" href="#parent-first-dependencies"></a>Parent First Dependencies</h3>
<div class="paragraph">
<p>There are some classes that should not be loaded in an isolated manner, but that should always be loaded by the system
ClassLoader (or whatever ClassLoader is responsible for bootstrapping Quarkus). Most extensions do not need to worry about
this, however there are a few cases where this is necessary:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Some logging related classes, as logging must be loaded by the system ClassLoader</p>
</li>
<li>
<p>Quarkus bootstrap itself</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>If this is required it can be configured in the <code>quarkus-bootstrap-maven-plugin</code>. Note that if you
mark a dependency as parent first then all of its dependencies must also be parent first,
or a <code>LinkageError</code> can occur.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;plugin&gt;
    &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
    &lt;artifactId&gt;quarkus-bootstrap-maven-plugin&lt;/artifactId&gt;
    &lt;configuration&gt;
        &lt;parentFirstArtifacts&gt;
            &lt;parentFirstArtifact&gt;io.quarkus:quarkus-bootstrap-core&lt;/parentFirstArtifact&gt;
            &lt;parentFirstArtifact&gt;io.quarkus:quarkus-development-mode-spi&lt;/parentFirstArtifact&gt;
            &lt;parentFirstArtifact&gt;org.jboss.logmanager:jboss-logmanager-embedded&lt;/parentFirstArtifact&gt;
            &lt;parentFirstArtifact&gt;org.jboss.logging:jboss-logging&lt;/parentFirstArtifact&gt;
            &lt;parentFirstArtifact&gt;org.ow2.asm:asm&lt;/parentFirstArtifact&gt;
        &lt;/parentFirstArtifacts&gt;
    &lt;/configuration&gt;
&lt;/plugin&gt;</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="banned-dependencies"><a class="anchor" href="#banned-dependencies"></a>Banned Dependencies</h3>
<div class="paragraph">
<p>There are some dependencies that we can be sure we do not want. This generally happens when a dependency has had a name
change (e.g. smallrye-config changing groups from <code>org.smallrye</code> to <code>org.smallrye.config</code>, the <code>javax</code> &#8594; <code>jakarta</code> rename).
This can cause problems, as if these artifacts end up in the dependency tree out of date classes can be loaded that are
not compatible with Quarkus. To deal with this extensions can specify artifacts that should never be loaded. This is
done by modifying the <code>quarkus-bootstrap-maven-plugin</code> config in the pom (which generates the <code>quarkus-extension.properties</code>
file). Simply add an <code>excludedArtifacts</code> section as shown below:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;plugin&gt;
    &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
    &lt;artifactId&gt;quarkus-bootstrap-maven-plugin&lt;/artifactId&gt;
    &lt;configuration&gt;
        &lt;excludedArtifacts&gt;
            &lt;excludedArtifact&gt;io.smallrye:smallrye-config&lt;/excludedArtifact&gt;
            &lt;excludedArtifact&gt;javax.enterprise:cdi-api&lt;/excludedArtifact&gt;
        &lt;/excludedArtifacts&gt;
    &lt;/configuration&gt;
&lt;/plugin&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>This should only be done if the extension depends on a newer version of these artifacts. If the extension does not bring
in a replacement artifact as a dependency then classes the application needs might end up missing.</p>
</div>
</div>
</div>
</div>
    </div>
  </div>
</div>

  </div>

  <div class="content project-footer">
  <div class="footer-section">
    <div class="logo-wrapper">
      <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_reverse.svg" class="project-logo" title="Quarkus"></a>
    </div>
  </div>
  <div class="grid-wrapper">
    <p class="grid__item width-3-12">Quarkus is open. All dependencies of this project are available under the <a href='https://www.apache.org/licenses/LICENSE-2.0' target='_blank'>Apache Software License 2.0</a> or compatible license.<br /><br />This website was built with <a href='https://jekyllrb.com/' target='_blank'>Jekyll</a>, is hosted on <a href='https://pages.github.com/' target='_blank'>Github Pages</a> and is completely open source. If you want to make it better, <a href='https://github.com/quarkusio/quarkusio.github.io' target='_blank'>fork the website</a> and show us what you’ve got.</p>

    
      <div class="width-1-12 project-links">
        <span>Navigation</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="/">Home</a></li>
          
            <li><a href="/guides">Guides</a></li>
          
            <li><a href="/community/#contributing">Contribute</a></li>
          
            <li><a href="/faq">FAQ</a></li>
          
            <li><a href="/get-started">Get Started</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Contribute</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://twitter.com/quarkusio">Follow us</a></li>
          
            <li><a href="https://github.com/quarkusio">GitHub</a></li>
          
            <li><a href="/security">Security&nbsp;policy</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Get Help</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://groups.google.com/forum/#!forum/quarkus-dev">Forums</a></li>
          
            <li><a href="https://quarkusio.zulipchat.com">Chatroom</a></li>
          
        </ul>
      </div>
    

    
      <div class="width-3-12 more-links">
        <span>Quarkus is made of community projects</span>
        <ul class="footer-links">
          
            <li><a href="https://vertx.io/" target="_blank">Eclipse Vert.x</a></li>
          
            <li><a href="https://microprofile.io" target="_blank">Eclipse MicroProfile</a></li>
          
            <li><a href="https://hibernate.org" target="_blank">Hibernate</a></li>
          
            <li><a href="https://netty.io" target="_blank">Netty</a></li>
          
            <li><a href="https://resteasy.github.io" target="_blank">RESTEasy</a></li>
          
            <li><a href="https://camel.apache.org" target="_blank">Apache Camel</a></li>
          
            <li><a href="https://code.quarkus.io/" target="_blank">And many more...</a></li>
          
        </ul>
      </div>
    
  </div>
</div>
  <div class="content redhat-footer">
  <div class="grid-wrapper">
    <span class="licence">
      <i class="fab fa-creative-commons"></i><i class="fab fa-creative-commons-by"></i> <a href="https://creativecommons.org/licenses/by/3.0/" target="_blank">CC by 3.0</a> | <a href="https://www.redhat.com/en/about/privacy-policy">Privacy Policy</a>
    </span>
    <span class="redhat">
      Sponsored by
    </span>
    <span class="redhat-logo">
      <a href="https://www.redhat.com/" target="_blank"><img src="/assets/images/redhat_reversed.svg"></a>
    </span>
  </div>
</div>


  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" integrity="sha384-8gBf6Y4YYq7Jx97PIqmTwLPin4hxIzQw5aDmUg/DDhul9fFpbbLcLh3nTIIDJKhx" crossorigin="anonymous"></script>
  <script type="text/javascript" src="/assets/javascript/mobile-nav.js"></script>
  <script type="text/javascript" src="/assets/javascript/scroll-down.js"></script>
  <script src="/assets/javascript/satellite.js" type="text/javascript"></script>
  <script src="https://quarkus.io/guides/javascript/config.js" type="text/javascript"></script>
  <script src="/assets/javascript/search-filter.js" type="text/javascript"></script>
  <script src="/assets/javascript/back-to-top.js" type="text/javascript"></script>
</body>

</html>
